<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <script>
            ////T1
            // var F = function () {};
            // Object.prototype.a = function () {
            //     console.log("a");
            // };
            // Function.prototype.b = function () {
            //     console.log("b");
            // };
            // var f = new F();
            // // f是构造函数F的一个实例对象，在调用a()时，先在f本身中查找是否有a方法，没有然通过原型链向上在F.prototype中找，仍然没有，此时继续向上查找，在Object.prototype中找到了方法a，于是调用这个方法a，打印a
            // f.a(); // a
            // // 同上，在Ojbect.prototype中没有找到b方法后，继续向上的原型链顶端为null，所以未能查找到b方法，报错
            // f.b(); // 报错
            // // 在F调用a，b方法时，会通过原型链找到Function.prototype, 找到b方法，打印b，继续向上找，在Object.prototype中找到a方法，打印a
            // F.a(); // a
            // F.b(); // b

            //   //T2
            // var A = function () {};
            // A.prototype.n = 1;
            // var b = new A();
            // A.prototype = {
            //     n: 2,
            //     m: 3,
            // };
            // var c = new A();
            // // 虽然在A.prototype重新赋值为对象{n: 2,m: 3,}的引用地址，但是在上段var b = new A();中，实例b.__proto__一直是指向修改前的A.prototype的，内存中还未销毁
            // console.log(b.n); // 1 在打印b.n时,随着原型链查找,在修改前的A.prototype中找到
            // console.log(b.m); // undefined 所以打印b.m时，之前的A.prototype中并未有m属性，继续向Object中找直至null停止也没有找到，打印undifined
            // console.log(c.n); // 2  在打印c.n和c.m时，虽然自身没有n和m属性，但是顺着原型链向上在修改后的A.prototype中找到，所以打印2和 3
            // console.log(c.m); // 3

            //   //T3
            // var foo = {},
            //     F = function () {};
            // Object.prototype.a = "value a";
            // Function.prototype.b = "value b";
            // // 这题和T1同理，只是将T1中的方法改为了属性，但按照原型链向上找顺序是一样
            // console.log(foo.a); // value a
            // console.log(foo.b); // undefined
            // console.log(F.a); // value a
            // console.log(F.b); // value b

            //   //T4
            //     function A() {}
            //     function B(a) {
            //         this.a = a;
            //     }
            //     function C(a) {
            //         if (a) {
            //             this.a = a;
            //         }
            //     }
            //     A.prototype.a = 1;
            //     B.prototype.a = 1;
            //     C.prototype.a = 1;
            //     // new A()返回的实例中没有a，顺着原型链向上到A.prototype找，找到a=1，所以打印1
            //     console.log(new A().a); // 1
            //     // new B()返回的实例中有a，因为在new之后，this会指向实例，但是由于并未传递参数a，所以在this.a并未赋值，打印undefined
            //     console.log(new B().a); // undefined
            //     // 和b相似，但是传递了值为2的a参数，if判断后this.a赋值为2
            //     console.log(new C(2).a); // 2
            //
        </script>
    </body>
</html>
